import type { CascaderOptions, CascaderOptionsData } from '../../types/options';

/**
 * 搜索结果项类型
 */
export interface SearchResultItem {
    /**
     * 匹配的数据项
     */
    data: CascaderOptionsData;
    
    /**
     * 数据项的路径
     */
    path: string[];
}

/**
 * 获取下一级数据
 * @param value 当前选中的值
 * @param options 级联选择器配置
 * @returns 下一级数据数组
 */
export function getNextLevelData(value: (string|number)[] = [], options: CascaderOptions): CascaderOptionsData[] {
    const { data = [] } = options;

    return value.reduce((acc, cur) => {
        return acc.find((ele) => ele.value === cur)?.children ?? [];
    }, data) as CascaderOptionsData[];
}

/**
 * 搜索数据
 * @param data 数据数组
 * @param keyword 搜索关键词
 * @param searchFn 自定义搜索函数
 * @returns 搜索结果数组
 */
export function searchData(
    data: CascaderOptionsData[], 
    keyword: string, 
    searchFn?: (data: CascaderOptionsData, keyword: string) => boolean
): SearchResultItem[] {
    if (!keyword || !data || data.length === 0) {
        return [];
    }

    return recursiveSearch(data, keyword, [], searchFn);
}

/**
 * 递归搜索数据
 * @param data 当前层级数据
 * @param keyword 搜索关键词
 * @param path 当前路径
 * @param searchFn 自定义搜索函数
 * @returns 搜索结果数组
 */
export function recursiveSearch(
    data: CascaderOptionsData[], 
    keyword: string, 
    path: string[] = [], 
    searchFn?: (data: CascaderOptionsData, keyword: string) => boolean
): SearchResultItem[] {
    const results: Array<{data: CascaderOptionsData, path: string[]}> = [];
    const lowerKeyword = keyword.toLowerCase();

    for (const item of data) {
        // 检查当前项是否匹配
        const isMatch = searchFn 
            ? searchFn(item, keyword) 
            : item.label.toLowerCase().includes(lowerKeyword);

        // 创建当前路径
        const currentPath = [...path, String(item.value)];

        // 如果匹配，添加到结果中
        if (isMatch) {
            results.push({ data: item, path: currentPath });
        }

        // 如果有子节点，继续递归搜索
        if (item.children && item.children.length > 0) {
            const childResults = recursiveSearch(item.children, keyword, currentPath, searchFn);
            results.push(...childResults);
        }
    }

    return results;
}